package com.siwei.mes.tgl.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.siwei.mes.entity.*;
import com.siwei.mes.entity.tgl.TglItemorder;
import com.siwei.mes.entity.tgl.TglTrwd;
import com.siwei.mes.enums.CheckEnum;
import com.siwei.mes.enums.MaterialsEnum;
import com.siwei.mes.mapper.*;
import com.siwei.mes.service.ExperimentService;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: 小票
 * @Version: 1.0
 * @author: chenmaolin
 * @date: 2024/1/1 14:09
 */
@Service
public class SyncTglItemorderService {
    private static final Logger log = LoggerFactory.getLogger("tgl");
    @Resource
    private TglItemorderMapper tglItemorderMapper;
    @Resource
    private CheckQuickConfigMapper checkQuickConfigMapper;
    @Resource
    private CheckBatchConfigMapper checkBatchConfigMapper;

    @Resource
    private ExperimentCheckItemorderMapper experimentCheckItemorderMapper;
    @Resource
    private ExperimentService experimentService;
    @Resource
    private ExperimentItemorderMapper experimentItemorderMapper;
    @Resource
    private ExperimentQuickRecordMapper experimentQuickRecordMapper;
    @Resource
    private ExperimentBatchRecordMapper experimentBatchRecordMapper;
    @Resource
    private ExperimentMapper experimentMapper;
    @Resource
    private ExperimentTaskMapper experimentTaskMapper;
    @Resource
    private TglTrwdMapper tglTrwdMapper;
    @Resource
    private TestProjectInfoMapper testProjectInfoMapper;
    @Resource
    private ExperimentDetailMapper experimentDetailMapper;
    @Resource
    private ExperimentSampleTestProjectMapper experimentSampleTestProjectMapper;
    @Resource
    private ExperimentSampleSmokeMapper experimentSampleSmokeMapper;

    public boolean genTglItemOrderTest(TglItemorder entity) {
        try {
            /**这里判断快检 创建混凝土台账*/
            boolean quickFlag = this.initQuickExperiment(entity);
            /**这里判断批检 创建混凝土台账*/
            boolean batchFlag = this.initBatchExperiment(entity);
            if (quickFlag && batchFlag) {
                tglItemorderMapper.updateIsGenInfo(entity.getId(), 1, "");
                return true;
            }
        } catch (Exception e) {
            tglItemorderMapper.updateIsGenInfo(entity.getId(), 2, e.getMessage());
            return true;
        }
        return true;
    }

    public boolean operateTglItemOrder(TglItemorder entity) {
        log.info("TGL新增小票,入参：{}", JSON.toJSONString(entity));

        entity.setPaninfo(StringEscapeUtils.unescapeJava(entity.getPaninfo()));
        entity.setExtrainfo(StringEscapeUtils.unescapeJava(entity.getExtrainfo()));

        /**根据Id判断是否存在*/
        TglItemorder localInfo = tglItemorderMapper.selectByItId(entity.getItid());
        if (localInfo != null) {
            /**小票不允许修改*/
            log.info("MES品控不支持修改小票，对应小票itid：【{}】", entity.getItid());
        } else {
            entity.setIsGenExperiment(0);
            tglItemorderMapper.insertSelective(entity);
            if (StringUtils.isNotBlank(entity.getTpz()) && entity.getFrwdh() != null) {
                try {
                    /**这里判断快检 创建混凝土台账*/
                    boolean quickFlag = this.initQuickExperiment(entity);
                    /**这里判断批检 创建混凝土台账*/
                    boolean batchFlag = this.initBatchExperiment(entity);
                    if (quickFlag && batchFlag) {
                        tglItemorderMapper.updateIsGenInfo(entity.getId(), 1, null);
                    }
                } catch (Exception e) {
                    tglItemorderMapper.updateIsGenInfo(entity.getId(), 2, e.getMessage());
                }
            }
        }
        return true;
    }

    /**
     * 创建批检混凝土台账  1个小票只有一个
     *
     * @param entity
     * @return
     */
    public boolean initBatchExperiment(TglItemorder entity) {
        try {
            Long experimentId = null;// 试验台账id
            String tpz = entity.getTpz();// 砼品种
            /**获取对应的tgl任务单信息*/
            TglTrwd tglTrwd = tglTrwdMapper.selectByFRwdh(entity.getFrwdh());
            if (tglTrwd == null) {
                log.info("tgl任务单信息不存在，直接跳过，任务单号：【{}】", entity.getFrwdh());
                return false;
            }
            String fphbno = tglTrwd.getFphbno();
            if (StringUtils.isBlank(fphbno)) {
                log.info("tgl任务单配合比没有，直接跳过，任务单好：【{}】", entity.getFrwdh());
            }
            /**需要生成对应试验台账的批检配置*/
            List<CheckBatchConfig> needGenBatchConfigList = new ArrayList<>();

            /**快检/批检与试验台账和小票的关系*/
            List<ExperimentCheckItemorder> needAddCheckItemorderList = new ArrayList<>();

            Set<String> entrustExperimentSet = new HashSet<>();// 委托试验名称
            /**试验项目code集合*/
            Set<String> testProjectCodeList = new HashSet<>();

            /**获取所有批检配置信息*/
            List<CheckBatchConfig> batchConfigList = checkBatchConfigMapper.getList(new CheckBatchConfig().setIsDel(0).setProjectCategory(MaterialsEnum.CONCRETE.getCode()));
            for (CheckBatchConfig batchConfig : batchConfigList) {
                Long batchRules = batchConfig.getBatchRules();// 批检规格 1-车车都检  2-按重量
                double batchThreshold = batchConfig.getBatchThreshold() == null ? 0.0 : batchConfig.getBatchThreshold();// 阈值
                if (batchRules == 1) {// 车车都检查
                    List<String> codeList = Arrays.asList(batchConfig.getTestProjectCode().split(","));
                    testProjectCodeList.addAll(codeList);

                    List<String> nameList = Arrays.asList(batchConfig.getTestProjectName().split(","));
                    entrustExperimentSet.addAll(nameList);

                    needGenBatchConfigList.add(batchConfig);
                } else if (batchRules == 2) {// 按重量
                    /**查询对应快检是否有之前的台账关联关系*/
                    ExperimentCheckItemorder checkItemorder = new ExperimentCheckItemorder().setPhb(fphbno)
                            .setCheckId(batchConfig.getId()).setCheckType(CheckEnum.BATCH.getCode());
                    List<ExperimentCheckItemorder> checkList = experimentCheckItemorderMapper.getList(checkItemorder);
                    // 之前的条数或者是方量
                    double totalThreshold = checkList.stream().map(ExperimentCheckItemorder::getFhQuantity).reduce((float) 0, Float::sum);
                    // 本次加上之前的条数或者方量
                    double addTotal = totalThreshold + entity.getFhquantity();

                    /**组装快检/批检与试验台账和小票的关系*/
                    ExperimentCheckItemorder checkInfo = new ExperimentCheckItemorder()
                            .setCheckId(batchConfig.getId()).setTpz(tpz).setPhb(fphbno)
                            .setCheckType(CheckEnum.BATCH.getCode()).setCreateTime(new Date()).setItemorderId(entity.getId())
                            .setExperimentId(experimentId);

                    /**如果之前的加上本次的 大于阈值需要生产一个新的试验台账记录否则就用之前的*/
                    if (addTotal > batchThreshold || checkList.isEmpty()) {// 如果大于阈值
                        List<String> codeList = Arrays.asList(batchConfig.getTestProjectCode().split(","));
                        testProjectCodeList.addAll(codeList);

                        List<String> nameList = Arrays.asList(batchConfig.getTestProjectName().split(","));
                        entrustExperimentSet.addAll(nameList);

                        needGenBatchConfigList.add(batchConfig);

                        for (ExperimentCheckItemorder checkItemorderInfo : checkList) {
                            experimentCheckItemorderMapper.deleteByPrimaryKey(checkItemorderInfo.getId());
                        }
                        needAddCheckItemorderList.add(checkInfo);
                    } else {
                        experimentId = checkList.get(0).getExperimentId();
                        needAddCheckItemorderList.add(checkInfo);
                    }
                }
            }

            /**如果试验台账id为空 就需要生成一个新的  如果有就只要加对应的子表记录 共用之前的试验台账记录*/
            if (experimentId == null) {
                StringBuilder entrustExperiment = new StringBuilder();
                for (String entrustExperimentName : entrustExperimentSet) {
                    entrustExperiment.append(entrustExperimentName).append(",");
                }

                /**新增混凝土试验台账*/
                Experiment experiment = experimentService.getExperimentInfoByItemOrderInfo(entity, CheckEnum.BATCH.getCode(), entrustExperiment.deleteCharAt(entrustExperiment.length() - 1).toString());
                experiment.setPhb(fphbno);
                experimentMapper.insertSelective(experiment);

                experimentId = experiment.getId();

                /**生成对应试验台账详情信息*/
                if (!testProjectCodeList.isEmpty()) {
                    List<ExperimentDetail> detailList = new ArrayList<>();
                    /**查询所有试验项目信息*/
                    List<TestProjectInfo> testProjectInfoList = testProjectInfoMapper.selectByTestProjectCodeList(testProjectCodeList);
                    for (TestProjectInfo testProjectInfo : testProjectInfoList) {
                        ExperimentDetail detail = new ExperimentDetail();
                        detail.setExperimentId(experiment.getId());
                        detail.setCheckType(2);
                        detail.tglInit(true);
                        detail.setTestProjectCode(testProjectInfo.getTestCode());
                        detail.setTestProjectName(testProjectInfo.getTestName());
                        detail.setObjJson(testProjectInfo.getObjJson());
                        detailList.add(detail);
                    }
                    if (!detailList.isEmpty()) {
                        experimentDetailMapper.insertList(detailList);
                    }

                    /**如果是批检 并且在抽样试验项目配置中 有记录 直接生成对应的抽样记录 t_experiment_sample_test_project*/
                    List<ExperimentSampleSmoke> sampleSmokeList = new ArrayList<>();
                    List<ExperimentSampleTestProject> sampleTestProjectList = experimentSampleTestProjectMapper.selectByTestProjectCodeList(testProjectCodeList);
                    for (ExperimentSampleTestProject sampleTestProject : sampleTestProjectList) {
                        Integer genNumber = sampleTestProject.getGenNumber();// 生成的条数
                        JSONArray genJson = sampleTestProject.getGenJson();// 生成对应的json
                        if (genJson.isEmpty() || genNumber == null || genNumber == 0) {
                            continue;
                        }
                        for (int i = 0; i < genNumber; i++) {
                            ExperimentSampleSmoke sampleSmoke = this.getExperimentSampleSmoke(sampleTestProject, experiment);
                            sampleSmokeList.add(sampleSmoke);
                        }
                    }
                    /**保存抽样信息*/
                    if (!sampleSmokeList.isEmpty()) {
                        experimentSampleSmokeMapper.insertList(sampleSmokeList);
                    }
                }
            }

            /**快检/批检与试验台账和小票的关系*/
            for (ExperimentCheckItemorder checkItemorder : needAddCheckItemorderList) {
                checkItemorder.setExperimentId(experimentId);
                experimentCheckItemorderMapper.insertSelective(checkItemorder);
            }

            /**新增试验台账对应小票数据*/
            experimentItemorderMapper.insertSelective(new ExperimentItemorder().setExperimentId(experimentId).setItemorderId(entity.getId()));


            /**新增试验台账对应tgl任务单记录*/
            ExperimentTask experimentTask = new ExperimentTask().setExperimentId(experimentId).setTaskId(tglTrwd.getId());
            if (experimentTaskMapper.selectOne(experimentTask) == null) {
                experimentTaskMapper.insertSelective(experimentTask);
            }

            /**新增试验台账对应批检配置记录*/
            for (CheckBatchConfig batchConfig : needGenBatchConfigList) {
                experimentBatchRecordMapper.insertSelective(new ExperimentBatchRecord().tglInit(true).setExperimentId(experimentId).setBatchId(batchConfig.getId()));
            }

            /**修改这个试验台账的代表数量 == 所有跟这个试验台账相关的小票发货数量之和*/
            List<TglItemorder> tglItemorderList = experimentItemorderMapper.selectByExperimentId(experimentId);
            double behalfNumber = tglItemorderList.stream().map(TglItemorder::getFhquantity).reduce((float) 0, Float::sum);
            Experiment experiment = new Experiment();
            experiment.setId(experimentId);
            experiment.setBehalfNumber(behalfNumber);
            experiment.tglInit(false);
            experimentMapper.updateByPrimaryKeySelective(experiment);
            return true;
        } catch (Exception e) {
            log.error("新增批检能生产的试验台账失败，入参：{}", JSON.toJSONString(entity), e);
            return false;
        }
    }

    /**
     * 创建快检混凝土台账
     *
     * @param entity
     */
    public boolean initQuickExperiment(TglItemorder entity) {
        try {
            Long experimentId = null;// 试验台账id
            String tpz = entity.getTpz();// 砼品种
            /**获取对应的tgl任务单信息*/
            TglTrwd tglTrwd = tglTrwdMapper.selectByFRwdh(entity.getFrwdh());
            String fphbno = tglTrwd.getFphbno();
            if (StringUtils.isBlank(fphbno)) {
                log.info("tgl任务单配合比没有，直接跳过，任务单好：【{}】", entity.getFrwdh());
            }
            /**需要生成对应试验台账的批检配置*/
            List<CheckQuickConfig> needGenQuickConfigList = new ArrayList<>();
            /**快检/批检与试验台账和小票的关系*/
            List<ExperimentCheckItemorder> needAddCheckItemorderList = new ArrayList<>();

            Set<String> entrustExperimentSet = new HashSet<>();// 委托试验名称
            /**试验项目code集合*/
            Set<String> testProjectCodeList = new HashSet<>();
            /**获取所有快检配置信息*/
            List<CheckQuickConfig> quickConfigList = checkQuickConfigMapper.select(new CheckQuickConfig().setIsDel(0).setProjectCategory(MaterialsEnum.CONCRETE.getCode()));
            for (CheckQuickConfig quickConfig : quickConfigList) {
                Long quickRules = quickConfig.getQuickRules();// 快检规则 1-小票数量  2-小票方量  3-车车都检
                if (quickRules == 1 || quickRules == 2) {
                    double quickThreshold = quickConfig.getQuickThreshold() == null ? 0.0 : quickConfig.getQuickThreshold();// 阈值
                    /**查询对应快检是否有之前的台账关联关系*/
                    ExperimentCheckItemorder checkItemorder = new ExperimentCheckItemorder().setPhb(fphbno)
                            .setCheckId(quickConfig.getId()).setCheckType(CheckEnum.QUICK.getCode());
                    List<ExperimentCheckItemorder> checkList = experimentCheckItemorderMapper.getList(checkItemorder);

                    double totalThreshold = 0;// 之前的条数或者是方量
                    double addTotal = 0;// 本次加上之前的条数或者方量
                    if (quickRules == 1) {
                        totalThreshold = checkList.size();
                        addTotal = totalThreshold + 1;
                    } else {
                        totalThreshold = checkList.stream().map(ExperimentCheckItemorder::getFhQuantity).reduce((float) 0, Float::sum);
                        addTotal = totalThreshold + entity.getFhquantity();
                    }

                    /**组装快检/批检与试验台账和小票的关系*/
                    ExperimentCheckItemorder checkInfo = new ExperimentCheckItemorder()
                            .setCheckId(quickConfig.getId()).setTpz(tpz).setPhb(fphbno)
                            .setCheckType(CheckEnum.QUICK.getCode()).setCreateTime(new Date()).setItemorderId(entity.getId())
                            .setExperimentId(experimentId);

                    /**如果之前的加上本次的 大于阈值需要生产一个新的试验台账记录否则就用之前的*/
                    if (addTotal > quickThreshold || checkList.isEmpty()) {
                        List<String> codeList = Arrays.asList(quickConfig.getTestProjectCode().split(","));
                        testProjectCodeList.addAll(codeList);

                        List<String> nameList = Arrays.asList(quickConfig.getTestProjectName().split(","));
                        entrustExperimentSet.addAll(nameList);

                        needGenQuickConfigList.add(quickConfig);
                        for (ExperimentCheckItemorder checkItemorderInfo : checkList) {
                            experimentCheckItemorderMapper.deleteByPrimaryKey(checkItemorderInfo.getId());
                        }
                        needAddCheckItemorderList.add(checkInfo);
                    } else {
                        experimentId = checkList.get(0).getExperimentId();
                        needAddCheckItemorderList.add(checkInfo);
                    }
                } else if (quickRules == 3) {// 车车都检 直接生成
                    List<String> codeList = Arrays.asList(quickConfig.getTestProjectCode().split(","));
                    testProjectCodeList.addAll(codeList);

                    List<String> nameList = Arrays.asList(quickConfig.getTestProjectName().split(","));
                    entrustExperimentSet.addAll(nameList);

                    needGenQuickConfigList.add(quickConfig);
                }
            }


            /**如果试验台账id为空 就需要生成一个新的  如果有就只要加对应的子表记录 共用之前的试验台账记录*/
            if (experimentId == null) {
                StringBuilder entrustExperiment = new StringBuilder();
                for (String entrustExperimentName : entrustExperimentSet) {
                    entrustExperiment.append(entrustExperimentName).append(",");
                }

                /**新增混凝土试验台账*/
                Experiment experiment = experimentService.getExperimentInfoByItemOrderInfo(entity, CheckEnum.QUICK.getCode(), entrustExperiment.deleteCharAt(entrustExperiment.length() - 1).toString());
                experiment.setPhb(fphbno);
                experimentMapper.insertSelective(experiment);

                /**这里赋值对应的试验台账信息*/
                experimentId = experiment.getId();

                /**生成对应试验台账详情信息*/
                if (!testProjectCodeList.isEmpty()) {
                    List<ExperimentDetail> detailList = new ArrayList<>();
                    /**查询所有试验项目信息*/
                    List<TestProjectInfo> testProjectInfoList = testProjectInfoMapper.selectByTestProjectCodeList(testProjectCodeList);
                    for (TestProjectInfo testProjectInfo : testProjectInfoList) {
                        ExperimentDetail detail = new ExperimentDetail();
                        detail.setExperimentId(experiment.getId());
                        detail.setCheckType(1);
                        detail.tglInit(true);
                        detail.setTestProjectCode(testProjectInfo.getTestCode());
                        detail.setTestProjectName(testProjectInfo.getTestName());
                        detail.setObjJson(testProjectInfo.getObjJson());
                        detailList.add(detail);
                    }
                    if (!detailList.isEmpty()) {
                        experimentDetailMapper.insertList(detailList);
                    }

                    /**新增对应快检的抽样信息*/
                    List<ExperimentSampleSmoke> sampleSmokeList = new ArrayList<>();
                    for (TestProjectInfo testProjectInfo : testProjectInfoList) {
                        ExperimentSampleSmoke sampleSmoke = new ExperimentSampleSmoke();
                        sampleSmoke.setId(null);
                        sampleSmoke.tglInit(true);
                        sampleSmoke.setExperimentId(experiment.getId());
                        sampleSmoke.setSampleTime(new Date());
                        sampleSmoke.setIsTestBlock(0);// 是否是试块 1-是 0-不是
                        sampleSmoke.setTestProjectCode(testProjectInfo.getTestCode());
                        sampleSmoke.setTestProjectName(testProjectInfo.getTestName());
                        sampleSmoke.setSampleUse(testProjectInfo.getTestName());
                        sampleSmoke.setSamplePersonName(experiment.getEntrustPersonName());
                        sampleSmoke.setDisposerPersonName(experiment.getEntrustPersonName());
                        sampleSmokeList.add(sampleSmoke);
                    }
                    if (!sampleSmokeList.isEmpty()) {
                        experimentSampleSmokeMapper.insertList(sampleSmokeList);
                    }
                }
            }

            /**快检/批检与试验台账和小票的关系*/
            for (ExperimentCheckItemorder checkItemorder : needAddCheckItemorderList) {
                checkItemorder.setExperimentId(experimentId);
                experimentCheckItemorderMapper.insertSelective(checkItemorder);
            }

            /**新增试验台账对应小票数据*/
            experimentItemorderMapper.insertSelective(new ExperimentItemorder().setExperimentId(experimentId).setItemorderId(entity.getId()));
            /**新增试验台账对应tgl任务单记录*/
            ExperimentTask experimentTask = new ExperimentTask().setExperimentId(experimentId).setTaskId(tglTrwd.getId());
            if (experimentTaskMapper.selectOne(experimentTask) == null) {
                experimentTaskMapper.insertSelective(experimentTask);
            }

            /**新增试验台账对应快检配置记录*/
            for (CheckQuickConfig quickConfig : needGenQuickConfigList) {
                experimentQuickRecordMapper.insertSelective(new ExperimentQuickRecord().tglInit(true).setExperimentId(experimentId).setQuickId(quickConfig.getId()));
            }

            /**修改这个试验台账的代表数量 == 所有跟这个试验台账相关的小票发货数量之和*/
            List<TglItemorder> tglItemorderList = experimentItemorderMapper.selectByExperimentId(experimentId);
            double behalfNumber = tglItemorderList.stream().map(TglItemorder::getFhquantity).reduce((float) 0, Float::sum);
            Experiment experiment = new Experiment();
            experiment.setId(experimentId);
            experiment.setBehalfNumber(behalfNumber);
            experiment.tglInit(false);
            experimentMapper.updateByPrimaryKeySelective(experiment);
            return true;
        } catch (Exception e) {
            log.error("新增快检能生产的试验台账失败，入参：{}", JSON.toJSONString(entity), e);
            return false;
        }
    }


    /**
     * 生成对应抽检信息
     *
     * @param sampleTestProject 抽检试验项目信息
     * @param experiment        试验台账信息
     * @return
     */
    private ExperimentSampleSmoke getExperimentSampleSmoke(ExperimentSampleTestProject sampleTestProject, Experiment experiment) {
        ExperimentSampleSmoke sampleSmoke = new ExperimentSampleSmoke();
        sampleSmoke.setId(null);
        sampleSmoke.tglInit(true);
        sampleSmoke.setExperimentId(experiment.getId());
        sampleSmoke.setSampleTime(new Date());
        sampleSmoke.setSampleTestProjectCode(sampleTestProject.getItemCode());
        sampleSmoke.setSampleTestProjectName(sampleTestProject.getItemName());
        sampleSmoke.setSampleTestProjectJson(sampleTestProject.getGenJson());
        sampleSmoke.setFreqNumber(sampleTestProject.getFreqNumber());
        sampleSmoke.setFreqUnit(sampleTestProject.getFreqUnit());
        sampleSmoke.setIsTestBlock(1);// 是否是试块 1-是 0-不是
        sampleSmoke.setTestProjectCode(sampleTestProject.getTestCode());
        sampleSmoke.setTestProjectName(sampleTestProject.getTestName());
        sampleSmoke.setSampleUse(sampleTestProject.getTestName());
        sampleSmoke.setSamplePersonName(experiment.getEntrustPersonName());
        sampleSmoke.setDisposerPersonName(experiment.getEntrustPersonName());
        return sampleSmoke;
    }
}
